#include "types.h"

#if 0
#define MDS_ROUND_BYTE( ROUND_LN2 ) ( (size_t)( 1 << (ROUND_LN2) ) )
#define MDS_ROUND_MASK( ROUND_LN2 ) ( (size_t)(MDS_ROUND_BYTE( ROUND_LN2 )-0x1) )
#define MDS_ROUND_NOT2( ROUND_LN2 ) ( (size_t)(~MDS_ROUND_MASK( ROUND_LN2 ) )   )
#define MDS_ROUND(ROUND_LN2,N)      ( ( (size_t)(N) + MDS_ROUND_MASK(ROUND_LN2) ) & MDS_ROUND_NOT2( ROUND_LN2 ) )

#define MDS_ROUND1(N)    MDS_ROUND(0,N)
#define MDS_ROUND2(N)    MDS_ROUND(1,N)
#define MDS_ROUND4(N)    MDS_ROUND(2,N)
#define MDS_ROUND8(N)    MDS_ROUND(3,N)
#define MDS_ROUND16(N)   MDS_ROUND(4,N)
#define MDS_ROUND32(N)   MDS_ROUND(5,N)
#define MDS_ROUND64(N)   MDS_ROUND(6,N)
#define MDS_ROUND128(N)  MDS_ROUND(7,N)
#define MDS_ROUND256(N)  MDS_ROUND(8,N)

#define MDS_MEMALIGN(N)    MDS_ROUND16(N)
#endif


void * mds_calloc(size_t count, size_t size)
{
	
	assert(size>0);
	{
		void *p = calloc( count, size);
		if( p )
		{
			const uint64_t n = ( (uint64_t)(count) ) * ( (uint64_t)(size) );
			mds_bytes += n;
			return p;
		}
		else 
		{
			return NULL;		
		}
		
	}
}

void   mds_free(void *p, size_t count, size_t size)
{
	assert(size>0);
	if( p )
	{
		const uint64_t n = ( (uint64_t)(count) ) * ( (uint64_t)(size) );
		assert( n <= mds_bytes );
		mds_bytes -= n;
		free( p );
	}
}

uint64_t mds_bytes = 0;

#include <stdarg.h>


void         mds_perror( FILE *fp, const char *when,...) 
{
	va_list ap;
	assert( when != NULL );
	assert( fp   != NULL );
	fprintf( fp, "**[LibC] '%s': ", strerror(errno) );
	va_start(ap,when);
	vfprintf(fp,when, ap);
	va_end(ap);
	fprintf(fp, "\n");
}


long mds_file_length( FILE *fp )
{
	long nb = -0;
	assert( fp );
	/* go to the end */
	if( fseek(fp, 0, SEEK_END) < 0 ) return -1;
	
	
	/* get #bytes */
	if( (nb = ftell(fp)) < 0 ) return -1;
	
	/* rewind */
	if( fseek(fp,0,SEEK_SET) < 0 ) return -1;
	
	return nb;
}

